﻿#region --- License & Copyright Notice ---
/*
ConsoleFx CommandLine Processing Library

Copyright (c) 2006-2012 Jeevan James
All rights reserved.

The contents of this file are made available under the terms of the
Eclipse Public License v1.0 (the "License") which accompanies this
distribution, and is available at the following URL:
http://opensource.org/licenses/eclipse-1.0.txt

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.

By using this software in any fashion, you are agreeing to be bound by the
terms of the License.
*/
#endregion

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

using ConsoleFx.Parsers;

namespace ConsoleFx.Programs
{
    public abstract class ResourceUsageBuilderBase : UsageBuilder
    {
        protected ResourceUsageBuilderBase(Parser parser)
            : base(parser)
        {
        }

        public bool CultureSpecific { get; set; }

        public override StringBuilder GenerateFullUsage()
        {
            var sb = new StringBuilder();

            //Build the list of cultures, from the most specific to the least, from the current UI culture
            var culturePriorityOrder = new List<CultureInfo>(3);
            CultureInfo culture = CultureInfo.CurrentUICulture;
            while (!Equals(culture, CultureInfo.InvariantCulture))
            {
                culturePriorityOrder.Add(culture);
                culture = culture.Parent;
            }
            culturePriorityOrder.Add(null);

            //The usage resource files should be in the entry assembly
            Assembly assembly = Assembly.GetEntryAssembly();
            string[] resourceNames = assembly.GetManifestResourceNames();

            foreach (CultureInfo culturePriorityItem in culturePriorityOrder)
            {
                string resourceName = culturePriorityItem != null
                    ? string.Format(culture, "Usage.{0}.txt", culturePriorityItem.Name) : "Usage.txt";
                string fullResourceName = Array.Find(resourceNames, name => name.EndsWith(resourceName, StringComparison.Ordinal));
                if (fullResourceName == null)
                    continue;

                using (Stream resourceStream = assembly.GetManifestResourceStream(fullResourceName))
                {
                    if (resourceStream == null)
                        throw new InvalidDataException("Could not read the assembly resource that contains the usage information");

                    using (var resourceReader = new StreamReader(resourceStream))
                    {
                        string usageText = resourceReader.ReadToEnd();
                        string resolvedUsageText = ResolverPattern.Replace(usageText, match => {
                            string variableName = match.Groups["variable"].Value;
                            PropertyInfo property = Parser.GetType().GetProperty(variableName, typeof(string), Type.EmptyTypes);
                            return property == null ? match.Value : property.GetValue(Parser, null).ToString();
                        });
                        sb.Append(resolvedUsageText);
                    }
                }

                break;
            }
            return sb;
        }

        private static readonly Regex ResolverPattern = new Regex(@"%(?<variable>\w+)%");
    }
}